package com.hqq.concurrency.read_write_lock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

/**
 * ReadWriteLock读写锁
 * 在一个多线程的环境下,不管是读还是写操作会尝试去同步共享资源.
 * 这会导致低性能,特别在读多于写的情况下,因为读操作对另一个线程来说的线程安全的
 * <p>
 * 这种模式允许同步的读操作,但是写操作会加排他锁.
 * 意味着多线程可以进行读操作,但是修改数据的时候需要加排他锁
 * 当一个线程在写数据时,其他读或写线程会一直阻塞到当前线程完成写操作
 * Created by heqianqian on 2017/7/30.
 */
public class App {

    private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        ReaderWriterLock readerWriterLock = new ReaderWriterLock();

        //开启5个读线程
        IntStream.range(0, 5)
                .forEach(i -> executorService.submit(new Reader("Reader" + i, readerWriterLock.readLock())));

        //开启5个写线程
        IntStream.range(0, 5)
                .forEach(i -> executorService.submit(new Writer("Writer" + i, readerWriterLock.writeLock())));

        executorService.shutdown();

        try {
            executorService.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            LOGGER.error("Error waiting for ExecutorService shutdown");
        }
    }

}
